<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="apple-mobile-web-app-status-bar-style" content="black" />
        <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0, maximum-scale=1.0, minimal-ui" />
        
        <title>Table Design</title>
        
        <script src="../../js/greyspots.js" type="text/javascript"></script>
        <link href="../../css/greyspots.css" type="text/css" rel="stylesheet" />
        
        <link href="../../css/postage.css" type="text/css" rel="stylesheet" />
        
        <script src="../resources/ws-get-functions.js" type="text/javascript"></script>
        
        <!-- right now these scripts are hard coded for postgres 9.2 -->
        <script src="../resources/pg-9.2-tree-functions.js" type="text/javascript"></script>
        <script src="../resources/pg-9.2-tree-queries.js" type="text/javascript"></script>
        
        <script src="../../js/page-zoom.js" type="text/javascript"></script>

        <script>
        //COLUMN REORDER NOT WORKING
            var strTableName, strSchemaName, strHasOids, strConstraints, arrConstraint, strGrantsEtc, arrColumn = [], strRelOptions, dependency_script, strOwner, arrConstraint = [];
            var strDumpQuery = ''
            scriptQuery.ruleSql = ml(function () {/*
                   SELECT   E'-- DROP RULE ' || quote_ident(pg_rewrite.rulename) || ' ON ' || quote_ident(pg_namespace.nspname) || '.' || quote_ident(pg_class.relname) || E';\n' ||
                            E'\nCREATE OR REPLACE ' || substring(pg_get_ruledef(pg_rewrite.oid, true), 8) ||
                            E'\n\n'
                     FROM pg_class
                LEFT JOIN pg_rewrite ON pg_class.oid = pg_rewrite.ev_class
                LEFT JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
                    WHERE pg_rewrite.oid = {{INTOID}};
                * /});
            
            scriptQuery.triggerSql = ml(function () {/*
                   SELECT   '-- Trigger: ' || quote_ident(pg_trigger.tgname) || ' ON ' || quote_ident(nspname) || '.' || quote_ident(relname) || E';\n\n' || 
                            '-- DROP TRIGGER ' || quote_ident(pg_trigger.tgname) || ' ON ' || quote_ident(nspname) || '.' || quote_ident(relname) || E';\n\n' ||
                            regexp_replace(regexp_replace(regexp_replace(regexp_replace(pg_get_triggerdef(pg_trigger.oid, true),
                            ' BEFORE ', E'\n   BEFORE '), ' ON ', E'\n   ON '), ' FOR ', E'\n   FOR '), ' EXECUTE ', E'\n   EXECUTE ') || E';\n\n'
                    FROM pg_class 
                    JOIN pg_trigger ON pg_trigger.tgrelid = pg_class.oid
                    JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
                   WHERE pg_trigger.oid = {{INTOID}};
                */});
            
            listQuery.tableData = ml(function(){/*
                     -- non-CHECK CONSTRAINTs
                     SELECT 'CONSTRAINT ' || pg_constraint.conname || ' ' || pg_get_constraintdef(pg_constraint.oid, true)
                       FROM pg_class
                  LEFT JOIN pg_constraint ON pg_constraint.conrelid = pg_class.oid
                      WHERE pg_constraint.oid IS NOT NULL AND pg_class.oid = {{INTOID}}
                     UNION ALL
                     -- CHECK CONSTRAINTs
                     SELECT 'CONSTRAINT ' || conname || ' ' || pg_get_constraintdef(pg_constraint.oid, true)
                       FROM pg_constraint
                       JOIN pg_class pg_class ON pg_class.oid = conrelid
                       JOIN pg_namespace nl ON nl.oid = relnamespace
            LEFT OUTER JOIN pg_description des ON des.objoid = pg_constraint.oid
                      WHERE contype = 'c' AND pg_class.oid = {{INTOID}};
                    
                    SELECT COALESCE((SELECT E'\n\n' || (SELECT array_to_string(array_agg( 'GRANT ' || 
                        (SELECT array_to_string((SELECT array_agg(perms ORDER BY srt)
                        FROM (    SELECT 1 as srt, CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ 'r($|[^*])' THEN 'SELECT' END as perms
                            UNION SELECT 2, CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ 'w($|[^*])' THEN 'UPDATE' END
                            UNION SELECT 3, CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ 'a($|[^*])' THEN 'INSERT' END
                            UNION SELECT 4, CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ 'd($|[^*])' THEN 'DELETE' END
                            UNION SELECT 5, CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ 'D($|[^*])' THEN 'TRUNCATE' END
                            UNION SELECT 6, CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ 'x($|[^*])' THEN 'REFERENCES' END
                            UNION SELECT 7, CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ 't($|[^*])' THEN 'TRIGGER' END ) em
                            WHERE perms is not null),',')) ||
                        ' ON TABLE ' || quote_ident(pg_namespace.nspname) || '.' || quote_ident(pg_class.relname) || ' TO ' ||
                        CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[1] = '' THEN 'public' ELSE (regexp_split_to_array(unnest::text,'[=/]'))[1] END || 
                        ';' ), E'\n')
                        FROM unnest(relacl) 
                        WHERE (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ '(r|w|a|d|D|x|t)($|[^*])' 
                        )
                    FROM pg_class 
                    JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
                    WHERE pg_class.oid = {{INTOID}} ),'')
                    
                    ||  COALESCE((SELECT E'\n\n' || (SELECT array_to_string(array_agg( 'GRANT ' || 
                        (SELECT array_to_string((SELECT array_agg(perms ORDER BY srt)
                        FROM (    SELECT 1 as srt, CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ 'r\*' THEN 'SELECT' END as perms
                            UNION SELECT 2, CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ 'w\*' THEN 'UPDATE' END
                            UNION SELECT 3, CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ 'a\*' THEN 'INSERT' END
                            UNION SELECT 4, CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ 'd\*' THEN 'DELETE' END
                            UNION SELECT 5, CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ 'D\*' THEN 'TRUNCATE' END
                            UNION SELECT 6, CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ 'x\*' THEN 'REFERENCES' END
                            UNION SELECT 7, CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ 't\*' THEN 'TRIGGER' END ) em
                            WHERE perms is not null),',')) ||
                        ' ON TABLE ' || quote_ident(pg_namespace.nspname) || '.' || quote_ident(pg_class.relname) || ' TO ' ||
                        CASE WHEN (regexp_split_to_array(unnest::text,'[=/]'))[1] = '' THEN 'public' ELSE quote_ident((regexp_split_to_array(unnest::text,'[=/]'))[1]) END || 
                        ' WITH GRANT OPTION;'), E'\n')
                        FROM unnest(relacl) 
                        WHERE (regexp_split_to_array(unnest::text,'[=/]'))[2] ~ '(r|w|a|d|D|x|t)\*' )
                    FROM pg_class 
                    JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
                    WHERE pg_class.oid = {{INTOID}} ), '')
                    
                    || COALESCE(
                    (SELECT E'\n\n' || array_to_string((SELECT array_agg(ok.perms || E'\n') FROM (SELECT 'GRANT ' || (SELECT array_to_string((SELECT array_agg(perms)
                        FROM (    SELECT 4, CASE WHEN (regexp_split_to_array((att.attacl)::text, '[=/]'))[2] ~ 'r[^*]' THEN 'SELECT(' || att.attname || ')' END as perms
                            UNION SELECT 3, CASE WHEN (regexp_split_to_array((att.attacl)::text, '[=/]'))[2] ~ 'w[^*]' THEN 'UPDATE(' || att.attname || ')' END
                            UNION SELECT 2, CASE WHEN (regexp_split_to_array((att.attacl)::text, '[=/]'))[2] ~ 'a[^*]' THEN 'INSERT(' || att.attname || ')' END
                            UNION SELECT 1, CASE WHEN (regexp_split_to_array((att.attacl)::text, '[=/]'))[2] ~ 'x[^*]' THEN 'REFERENCES(' || att.attname || ')' END ) em
                            WHERE perms is not null
                            ORDER BY 1),','
                            )) ||
                        ' ON ' || quote_ident(pg_namespace.nspname) || '.' || quote_ident(pg_class.relname) || 
                        ' TO ' || CASE WHEN (regexp_split_to_array(att.attacl::text,'[=/]'))[1] = '' THEN 'public' ELSE quote_ident((regexp_split_to_array(att.attacl::text,'[=/]'))[1]) END ||
                        ';' as perms
                    FROM pg_class 
                    LEFT JOIN pg_attribute att ON att.attrelid = pg_class.oid 
                    JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
                    WHERE pg_class.oid = {{INTOID}} AND (regexp_split_to_array((att.attacl)::text, '[=/]'))[2] ~ 'r[^*]|w[^*]|a[^*]|x[^*]')ok),'')), '')
                    
                    || COALESCE((SELECT E'\n' || array_to_string((SELECT array_agg(ok.perms || E'\n') FROM (SELECT 'GRANT ' || (SELECT array_to_string((SELECT array_agg(perms)
                        FROM (    SELECT 4, CASE WHEN (regexp_split_to_array((att.attacl)::text, '[=/]'))[2] ~ 'r\*' THEN 'SELECT(' || att.attname || ')' END as perms
                            UNION SELECT 3, CASE WHEN (regexp_split_to_array((att.attacl)::text, '[=/]'))[2] ~ 'w\*' THEN 'UPDATE(' || att.attname || ')' END
                            UNION SELECT 2, CASE WHEN (regexp_split_to_array((att.attacl)::text, '[=/]'))[2] ~ 'a\*' THEN 'INSERT(' || att.attname || ')' END
                            UNION SELECT 1, CASE WHEN (regexp_split_to_array((att.attacl)::text, '[=/]'))[2] ~ 'x\*' THEN 'REFERENCES(' || att.attname || ')' END ) em
                            WHERE perms is not null
                            ORDER BY 1),','
                            )) ||
                        ' ON ' || quote_ident(pg_namespace.nspname) || '.' || quote_ident(pg_class.relname) || 
                        ' TO ' || CASE WHEN (regexp_split_to_array(att.attacl::text,'[=/]'))[1] = '' THEN 'public' ELSE quote_ident((regexp_split_to_array(att.attacl::text,'[=/]'))[1]) END  ||
                        ' WITH GRANT OPTION;' as perms
                    FROM pg_class 
                    LEFT JOIN pg_attribute att ON att.attrelid = pg_class.oid 
                    JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
                    WHERE pg_class.oid = {{INTOID}} AND (regexp_split_to_array((att.attacl)::text, '[=/]'))[2] ~ '(r|w|a|x)\*')ok),'')), '')


                    || COALESCE((SELECT E'\n\n' || array_to_string((SELECT array_agg(ok.perms || E'\n') FROM (
                    SELECT E'-- Index: ' || quote_ident(nsp.nspname) || '.' || quote_ident(clidx.relname) || 
                        E'\n\n-- DROP INDEX ' || quote_ident(nsp.nspname) || '.' || quote_ident(clidx.relname) || 
                        E';\n\n' ||
                        regexp_replace(regexp_replace(pg_get_indexdef(clidx.oid),' ON ', E'\n   ON '),
                        ' USING ', E'\n   USING ') || E';\n\n' as perms
                    FROM pg_class cl
                    JOIN pg_index idx ON cl.oid=idx.indrelid
                    JOIN pg_class clidx ON clidx.oid=idx.indexrelid
                    LEFT JOIN pg_namespace nsp ON nsp.oid = cl.relnamespace
                    WHERE cl.oid = {{INTOID}} AND (SELECT count(*) FROM pg_constraint con WHERE con.conindid = clidx.oid) = 0
                    )ok),'')), '');
                */});


            function UseError(table_name, schema_name, callback, dependency_text) {
                //console.log(dependency_text);
                if (dependency_text) {
                    var query = dependency_text + '\nDROP TABLE ' + schema_name + '.' + table_name + ';\nROLLBACK;';
                } else {
                    var query = 'DROP TABLE ' + schema_name + '.' + table_name + ';\nROLLBACK;';
                }
                var dropPart, error;
                GS.requestRawFromSocket(GS.envSocket, query, function (data) {
                    //console.log(data);
                    if (data.error_detail) {
                        error = data.error_detail;
                    }

                    if (error) {
                        var arrError = error.split('\n');
                        var i = 0, len = arrError.length;
                        while (i < len) {
                            if (arrError[i].trim().substring(0, 10).toLowerCase() === 'constraint') {
                                arrError.splice(i, 1);
                                i -= 1;
                                len -= 1;
                            }
                            i += 1;
                        }
                        if (arrError.length === 0) {
                            error = undefined;
                        }
                    }
                    if (error) {
                        dropPart = error.substring(0, error.toLowerCase().indexOf('depends on'));
                        if (dropPart.trim().substring(0, 10).toLowerCase() === 'constraint') {
                            arrConstraint.push(dropPart);
                            dropPart = '';

                        } else if (dependency_text) {
                            dropPart = 'DROP ' + dropPart.trim() + ';\n' + dependency_text + '';
                        } else {
                            dropPart = 'DROP ' + dropPart.trim() + ';';
                        }
                        UseError(table_name, schema_name, callback, dropPart);
                    } else {
                        if (callback) {
                            callback(query);
                        }
                        return query;
                    }
                });
            }

            function GetSequences(table_name, schema_name, callback) {
                var arrRows = [];
                GS.requestRawFromSocket(GS.envSocket, ml(function () {/*
                    SELECT pg_depend.objid::regclass AS relname, pg_attribute.attname
                        FROM pg_depend
                        LEFT JOIN pg_attribute ON pg_attribute.attrelid = pg_depend.refobjid AND pg_attribute.attnum = pg_depend.refobjsubid
                        LEFT JOIN pg_class ON pg_class.oid = pg_depend.objid
                        WHERE pg_depend.refobjid = $WONTGUESS9o8123475098yefd09vyu09817345${{SCHEMA}}.{{RELNAME}}$WONTGUESS9o8123475098yefd09vyu09817345$::regclass AND pg_class.relkind = 'S';
                */}).replace ('{{SCHEMA}}', schema_name).replace ('{{RELNAME}}', table_name), function (data, error) {
                    if (!error) {
                        if (data.bolLastMessage) {
                            var strQuery1 = '';
                            var strQuery2 = '';
                            var i = 0, len = arrRows.length;
                            console.log(arrRows);
                            while (i < len) {
                                console.log(i, len);
                                var arrRow = arrRows[i].split('\t');
                                strQuery1 += 'ALTER SEQUENCE ' + arrRow[0] + ' OWNED BY NONE;\n';
                                strQuery2 += 'ALTER SEQUENCE ' + arrRow[0] + ' OWNED BY ' + schema_name + '.' + table_name + '.' + quote_ident(arrRow[1]) + ';\n';
                                i += 1;
                            }
                            
                            console.log(strQuery1, strQuery2);
                            callback(strQuery1, strQuery2)
                        } else if (data.strMessage !== '\\.') {
                            arrRows.push.apply(arrRows, data.strMessage.split('\n'));
                        }
                    } else {
                        GS.webSocketErrorDialog(data);
                    }
                });
            }

            function getSchemaOid(intI, arrDropObjects, callback) {
                schemaoidQuery = ml(function () {/*
                    SELECT oid
                        FROM pg_namespace
                        WHERE nspname = '{{NAMETOKEN}}'
                        ORDER BY nspname;
                    */}).replace(/\{\{NAMETOKEN\}\}/g, arrDropObjects[intI][1]);

                getSingleCellData(schemaoidQuery, function (newSchemaOID) {
                    callback(newSchemaOID, intI);
                    var oidQuery = arrDropObjects[intI][3];
                    console.log(oidQuery);
                    getSingleCellData(oidQuery, function (newOID) {
                        arrDropObjects[intI][4] = newOID;
                        var scriptForCreate = arrDropObjects[intI][5].replace(/\{\{INTOID\}\}/gi, newOID);
                        getSingleCellData(scriptForCreate, function (dependddef) {
                            strDumpQuery += '\n\n\n' + dependddef + '\n';
                        });
                    });
                });
            }

            // function runCreateScripts(arrDropObjects) {
                
                
            // }

            function getDump(intSchemaOid) {
                var strQuery, handleListResults, strTableSuffix = Math.random().toString().substring(2), arrDropStatements, arrDropObjects = [], strTempObjName, strDropObjType, strDropSchema, strDropObjName;
                strDumpQuery = '';
                var strQuery, i, len, tempFunction, handleScriptResults, arrRow;


                strDumpQuery += '{{ALTERSEQUENCE}}'

                strDumpQuery += '\nALTER TABLE ' +
                                    strSchemaName + '.' + strTableName +
                                    ' RENAME TO ' + strTableName + strTableSuffix + ';\n';

                arrConstraint = strConstraints.split('\n');
                //console.log(strConstraints, arrConstraint);

                var intEndConstraintName;
                for (i = 0, len = arrConstraint.length; i < len; i += 1) {
                    if (arrConstraint[i].trim()) {
                        intEndConstraintName = arrConstraint[i].indexOf(' ');
                        intEndConstraintName = intEndConstraintName + arrConstraint[i].substring(intEndConstraintName + 1).indexOf(' ') + 1;
                        strDumpQuery += '\nALTER TABLE ';
                        strDumpQuery += strSchemaName;
                        strDumpQuery += '.';
                        strDumpQuery += strTableName;
                        strDumpQuery += strTableSuffix;
                        strDumpQuery += ' DROP ';
                        strDumpQuery += arrConstraint[i].substring(1, intEndConstraintName);
                        strDumpQuery += ';';
                    }
                }

                strDumpQuery += '\n\nCREATE TABLE ';
                strDumpQuery += strSchemaName;
                strDumpQuery += '.';
                strDumpQuery += strTableName;
                strDumpQuery += ' (\n';
                arrRow = document.querySelectorAll('tr');
                for (i = 1, len = arrRow.length - 1; i < len; i += 1) {
                    strDumpQuery += '\t';
                    strDumpQuery += arrRow[i].children[2].children[0].value;
                    strDumpQuery += ' ';
                    strDumpQuery += arrRow[i].children[3].children[0].value;
                    strDumpQuery += arrRow[i].children[4].children[0].value === 'true' ? ' NOT NULL' : '';
                    strDumpQuery += arrRow[i].children[5].children[0].value !== '' ? ' DEFAULT ' : '';
                    strDumpQuery += arrRow[i].children[5].children[0].value;

                    strDumpQuery += arrRow[i].children[6].children[0].value !== '' &&
                                    arrRow[i].children[6].children[0].value !== '0' &&
                                    arrRow[i].children[6].children[0].value !== 'default' ? ' COLLATE "' : '';

                    strDumpQuery += arrRow[i].children[6].children[0].value !== '' &&
                                    arrRow[i].children[6].children[0].value !== '0' &&
                                    arrRow[i].children[6].children[0].value !== 'default' ? arrRow[i].children[6].children[0].value : '';

                    strDumpQuery += arrRow[i].children[6].children[0].value !== '' &&
                                    arrRow[i].children[6].children[0].value !== '0' &&
                                    arrRow[i].children[6].children[0].value !== 'default' ? '"' : '';
                    strDumpQuery += (i + 1) < len || strConstraints.trim() !== '' ? ',\n' : '\n';
                }
                strDumpQuery += strConstraints;
                strDumpQuery += ')\n';
                strDumpQuery += 'WITH (\n';
                strDumpQuery += '\tOIDS=';
                strDumpQuery += strHasOids;
                if (strRelOptions === '\\N') {
                    strRelOptions = '';
                }
                strDumpQuery += strRelOptions !== '' ? ',\n\t' : '';
                strDumpQuery += strRelOptions;
                strDumpQuery += '\n';
                strDumpQuery += ');\n';
                strDumpQuery += 'ALTER TABLE ';
                strDumpQuery += strSchemaName;
                strDumpQuery += '.';
                strDumpQuery += strTableName;
                strDumpQuery += ' OWNER TO ';
                strDumpQuery += strOwner;
                strDumpQuery += ';\n';
                strDumpQuery += '{{HELPDEF}}\n';
                strDumpQuery += 'INSERT INTO ';
                strDumpQuery += strSchemaName;
                strDumpQuery += '.';
                strDumpQuery += strTableName;
                strDumpQuery += ' (';
                for (i = 0, len = arrColumn.length; i < len; i += 1) {
                    if (arrColumn[i].original) {
                        strDumpQuery += arrColumn[i].updated.name;
                        strDumpQuery += (i + 1) < len ? ', ' : '';
                    } else {
                        arrColumn.splice(i, 1);
                        i -= 1;
                        len -= 1;
                    }
                }
                strDumpQuery += ')\nSELECT ';
                for (i = 0, len = arrColumn.length; i < len; i += 1) {
                    if (arrColumn[i].original) {
                        strDumpQuery += arrColumn[i].original.name;
                        strDumpQuery += '::';
                        strDumpQuery += arrColumn[i].updated.type;
                        strDumpQuery += ' AS ';
                        strDumpQuery += arrColumn[i].updated.name;
                        strDumpQuery += (i + 1) < len ? ', ' : '\n';
                    }
                }
                strDumpQuery += 'FROM ';
                strDumpQuery += strSchemaName;
                strDumpQuery += '.';
                strDumpQuery += strTableName;
                strDumpQuery += strTableSuffix;
                strDumpQuery += ';\n\n';
                strDumpQuery += 'DROP TABLE ';
                strDumpQuery += strSchemaName;
                strDumpQuery += '.';
                strDumpQuery += strTableName;
                strDumpQuery += strTableSuffix;
                strDumpQuery += ';\n\n';

                console.log(strDumpQuery);

                UseError(strTableName, strSchemaName, function (query) {
                    GetSequences(strTableName, strSchemaName, function (query1, query2) {
                        strDumpQuery = query.substring(0, query.length - 10).substring(0, query.substring(0, query.length - 10).lastIndexOf('\n')) + '\n\n' + strDumpQuery;
                        arrDropStatements = query.substring(0, query.length - 10).substring(0, query.substring(0, query.length - 10).lastIndexOf('\n')).split('\n');
                        for (i = 0, len = arrDropStatements.length; i < len; i += 1) {
                            // removes 'DROP ' and ';'
                            strTempObjName = arrDropStatements[i].substring(5, arrDropStatements[i].length - 1);
                            // takes the first word
                            strDropObjType = strTempObjName.substring(0, strTempObjName.indexOf(' '));
                            // Capitalize first letter
                            strDropObjType = strDropObjType.substring(0, 1).toUpperCase() + strDropObjType.substr(1);
                            // removes the first word
                            strTempObjName = strTempObjName.substring(strDropObjType.length + 1, strTempObjName.length);
                            // first part
                            strDropSchema = strTempObjName.substring(0, strTempObjName.indexOf('.'));
                            // second part
                            strDropObjName = strTempObjName.substring(strDropSchema.length + 1, strTempObjName.length);
                            arrDropObjects.push(['' + strDropObjType + '', '' + strDropSchema + '', '' + strDropObjName + '']);
                        }
    
                        //add to beginning of arrDropObjects, the list of sequences
    
                        arrDropObjects = arrDropObjects.reverse();
                        var scriptForCreate = [], scriptForOid = [], schemaOID, arrDoneNumsOid;
                        
                        
                        for (i = 0, len = arrDropObjects.length; i < len; i += 1) {
                            
                            getSchemaOid(i, arrDropObjects, function (schemaOID, intI) {
                                if (arrDropObjects[intI][0].toLowerCase() === 'view') {
                                    scriptForOid = ml(function () {/*
                                        SELECT oid
                                            FROM pg_class
                                            WHERE relnamespace = '{{SCHEMAOID}}' AND relname = '{{NAMETOKEN}}'
                                        */}).replace(/\{\{NAMETOKEN\}\}/g, arrDropObjects[intI][2]).replace(/\{\{SCHEMAOID\}\}/g, schemaOID);
    
    
                                    scriptForCreate = scriptQuery.objectViewNoComment.replace(/{{STRNAME}}/gi, '' + arrDropObjects[intI][1] + '.' + arrDropObjects[intI][2] + '')
                                            .replace(/{{STRSQLSAFENAME}}/gi, '' + arrDropObjects[intI][1] + '.' + arrDropObjects[intI][2] + '')
                                            .replace(/{{SCHEMA}}/gi, arrDropObjects[intI][1])
                                            .replace(/{{STRRELNAME}}/gi, arrDropObjects[intI][2]);
                                } else if (arrDropObjects[intI][0].toLowerCase() === 'function') {
                                    scriptForOid = ml(function () {/*
                                            SELECT pr.oid
                                                FROM pg_proc pr
                                                JOIN pg_type typ ON typ.oid = pr.prorettype
                                                WHERE proisagg = FALSE AND typname <> 'trigger' AND pr.pronamespace = '{{SCHEMAOID}}' AND proname = '{{NAMETOKEN}}';
                                        */}).replace(/\{\{NAMETOKEN\}\}/g, arrDropObjects[intI][2]).replace(/\{\{SCHEMAOID\}\}/g, schemaOID);
    
    
                                    scriptForCreate = scriptQuery.objectFunction.replace(/{{STRNAME}}/gi, '' + arrDropObjects[intI][1] + '.' + arrDropObjects[intI][2] + '')
                                            .replace(/{{STRSQLSAFENAME}}/gi, '' + arrDropObjects[intI][1] + '.' + arrDropObjects[intI][2] + '')
                                            .replace(/{{SCHEMA}}/gi, arrDropObjects[intI][1])
                                            .replace(/{{STRRELNAME}}/gi, arrDropObjects[intI][2]);
                                } else if (arrDropObjects[intI][0].toLowerCase() === 'operator') {
                                    scriptForOid = ml(function () {/*  
                                        SELECT oprname
                                            FROM pg_operator
                                            WHERE (nsp.nspname || '.' || op.oprname || ' (' || format_type(op.oprleft, NULL) || ', ' || format_type(op.oprright, NULL) || ')') = '{{SCHEMAOID}}.{{NAMETOKEN}}';
                                    */}).replace(/\{\{NAMETOKEN\}\}/g, arrDropObjects[intI][2]).replace(/\{\{SCHEMAOID\}\}/g, schemaOID);
    
    
                                    scriptForCreate = scriptQuery.objectOperator.replace(/{{STRNAME}}/gi, '' + arrDropObjects[intI][1] + '.' + arrDropObjects[intI][2] + '')
                                            .replace(/{{STRSQLSAFENAME}}/gi, '' + arrDropObjects[intI][1] + '.' + arrDropObjects[intI][2] + '')
                                            .replace(/{{SCHEMA}}/gi, arrDropObjects[intI][1])
                                            .replace(/{{STRRELNAME}}/gi, arrDropObjects[intI][2]);
                                } else if (arrDropObjects[i][0].toLowerCase() === 'aggregate') {
                                    scriptForOid = ml(function () {/*
                                            SELECT pr.oid
                                                FROM pg_proc pr
                                                JOIN pg_type typ ON typ.oid = pr.prorettype
                                                WHERE proisagg = TRUE AND pr.pronamespace = '{{SCHEMAOID}}' AND proname = '{{NAMETOKEN}}';
                                        */}).replace(/\{\{NAMETOKEN\}\}/g, arrDropObjects[intI][2]).replace(/\{\{SCHEMAOID\}\}/g, schemaOID);
                                        
    
                                    scriptForCreate = scriptQuery.objectAggregate.replace(/{{STRNAME}}/gi, '' + arrDropObjects[intI][1] + '.' + arrDropObjects[intI][2] + '')
                                            .replace(/{{STRSQLSAFENAME}}/gi, '' + arrDropObjects[intI][1] + '.' + arrDropObjects[intI][2] + '')
                                            .replace(/{{SCHEMA}}/gi, arrDropObjects[intI][1])
                                            .replace(/{{STRRELNAME}}/gi, arrDropObjects[intI][2]);
                                }
                                arrDropObjects[intI][3] = scriptForOid;
                                arrDropObjects[intI][5] = scriptForCreate;
                            });
                        }
                        
                        
                        
                    /*
                    
                    
                                    getSingleCellData(scriptForCreate[arrDoneNumsOid.length - 1], function (script) {
                                        strDumpQuery += script;
                                        console.log(script);
                                    });
    .replace(/{{INTOID}}/gi, arrDropObjects[intI][4])
    .replace(/{{INTOID}}/gi, arrDropObjects[intI][4])
    .replace(/{{INTOID}}/gi, arrDropObjects[intI][4])
    .replace(/{{INTOID}}/gi, arrDropObjects[intI][4])
                        .replace(/{{INTOID}}/gi, oid)
                        .replace(/{{STRNAME}}/gi, strName)
                        .replace(/{{STRSQLSAFENAME}}/gi, sqlSafeName)
                        .replace(/{{SCHEMA}}/gi, schemaName)
                        .replace(/{{STRRELNAME}}/gi, relName);
                    */
                        schemaoidQuery = ml(function () {/*
                        SELECT oid
                            FROM pg_namespace
                            WHERE nspname = '{{NAMETOKEN}}'
                            ORDER BY nspname;
                        */}).replace(/\{\{NAMETOKEN\}\}/g, strSchemaName);
    
                    getSingleCellData(schemaoidQuery, function (newSchemaOID) {
                        schemaOID = newSchemaOID;
                        oidQuery = ml(function () {/*
                        SELECT oid
                            FROM pg_class
                            WHERE relnamespace = '{{SCHEMAOID}}' AND relname = '{{NAMETOKEN}}'
                        */}).replace(/\{\{NAMETOKEN\}\}/g, strTableName).replace(/\{\{SCHEMAOID\}\}/g, schemaOID);
                        
                        //console.log(oidQuery);
                        getSingleCellData(oidQuery, function (newOID) {
                            var tableRules = scriptQuery.objectTableNoCreate.replace(/\{\{INTOID\}\}/gi, newOID)
                            .replace(/\{\{STRSQLSAFENAME\}\}/gi, '' + strTableName + '.' + strSchemaName + '');
                            getSingleCellData(tableRules, function (tabledef) {
                                console.log(arrDropObjects);
                                strDumpQuery = strDumpQuery.replace(/\{\{ALTERSEQUENCE\}\}/gi, query1);
                                strDumpQuery = strDumpQuery.replace(/\{\{HELPDEF\}\}/gi, tabledef);
                    
                                strDumpQuery += query2;
                                //var triggQuery = ml(function () {/*SELECT string_agg('-- Trigger: ' || quote_ident(pg_trigger.tgname) || ' ON ' || quote_ident(nspname) || '.' || quote_ident(relname) || E';\n' || 
                                //	'DROP TRIGGER ' || quote_ident(pg_trigger.tgname) || ' ON ' || quote_ident(nspname) || '.' || quote_ident(relname) || E';\n' ||
                                //	regexp_replace(regexp_replace(regexp_replace(regexp_replace(pg_get_triggerdef(pg_trigger.oid, true),
                                //	' BEFORE ', E'\n   BEFORE '), ' ON ', E'\n   ON '), ' FOR ', E'\n   FOR '), ' EXECUTE ', E'\n   EXECUTE ') || E';', E'\n\n') as perms
                                //FROM pg_class 
                                //JOIN pg_trigger ON pg_trigger.tgrelid = pg_class.oid
                                //JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
                                //WHERE tgrelid <> {{INTOID}} AND pg_trigger.tgname ILIKE '%{{RELNAME}}%' AND pg_trigger.tgisinternal != TRUE*/}).replace(/\{\{INTOID\}\}/gi, newOID).replace(/\{\{RELNAME\}\}/gi, strTableName);
                                
                                //getSingleCellData(triggQuery, function (triggdefs) {
                                //    strDumpQuery += triggdefs;
                                
    var userNotes = '-- ##########################################################################################\n';
        userNotes += '-- ##########################################################################################\n';
        userNotes += '-- \n';
        userNotes += '--    PLEASE READ!!\n';
        userNotes += '--\n';
        userNotes += '--  This script DROPs and CREATEs all the objects that MUST to be altered for your changes to\n';
        userNotes += '--     run. However, PostgreSQL does not detect dependencies in some objects, such as \n';
        userNotes += '--     FUNCTIONs and TRIGGER FUNCTIONs. FUNCTIONs and TRIGGER FUNCTIONs could contain \n';
        userNotes += '--     references to any one of the objects below. If you need to make a change to any of\n';
        userNotes += '--     the objects below to run this script, then make sure you search for references to that\n';
        userNotes += '--     object. \n';
        userNotes += '\n';
        userNotes += '-- Postage provides the following workflow to search for object references:\n';
        userNotes += '--     \n';
        userNotes += '--     On the left side of the screen, click on any SCHEMA in the Object Tree.\n';
        userNotes += '--     On the right, click on "Dump Schema to Script"\n';
        userNotes += '--     We recommend you deselect "ALL" and then select FUNCTIONs and TRIGGER FUNCTIONs\n';
        userNotes += '--     Select any additional item types that may reference your object. \n';
        userNotes += '--     Click "Open Script" and wait for your script to be generated. This can take a minute.\n';
        userNotes += '--     Your script will appear in a new tab. \n';
        userNotes += '--     Now you can use the FIND functionality to look for your objects.\n';
        userNotes += '--\n';
        userNotes += '-- ##########################################################################################\n';
        userNotes += '-- ##########################################################################################\n\n';
                                
            strDumpQuery = userNotes + strDumpQuery;                    
                                    window.top.newTab('sql', strSchemaName + '.' + strTableName, {'strContent': strDumpQuery});
                                    GS.removeLoader('generate-script');
                                //});
                            });
                        });
                    });
                });
            });
        }


            function initTableDesign(arrColumns, strColumnData) {
                'use strict';
                var i, len, col_i, col_len, arrColumns, arrColumnTypes, arrRecords, arrRecord, recordHTML, strRecords, sortColumnHandler;

                //console.log(strTableName, strColumnData);

                // if last character is a \n: remove it
                if (strColumnData[strColumnData.length - 1] === '\n') {
                    strColumnData = strColumnData.substring(0, strColumnData.length - 1);
                }

                // split records
                arrRecords = strColumnData.split('\n');

                //console.log(arrColumns, arrColumnTypes, arrRecords);

                // build json object
                for (i = 0, len = arrRecords.length; i < len; i += 1) {
                    arrRecord = arrRecords[i].split('\t');

                    arrRecords[i] = {};
                    arrRecords[i].grid_record_number = i + 1;

                    for (col_i = 0, col_len = arrRecord.length; col_i < col_len; col_i += 1) {
                        arrRecords[i][arrColumns[col_i]] = GS.decodeFromTabDelimited(arrRecord[col_i]);
                    }

                    arrColumn.push({
                        original: {
                            name: arrRecords[i].attname
                        },
                        updated: {
                            name: arrRecords[i].attname,
                            type: arrRecords[i].format_type
                        }
                    });
                }

                //console.log(arrRecords);

                //attname\tformat_type\tcol_not_null\tcol_default\tcoll_collation
                recordHTML = ml(function () {/*
                    <th>{{! row.grid_record_number }}</th>
                    <td><gs-button mini icononly class="drag-handle" icon="bars"></gs-button></td>
                    <td><gs-text mini column="attname" value="{{! row['attname'] }}" placeholder="Column Name" data-value="{{! row['attname'] }}"/></td>
                    <td><gs-text mini column="format_type" value="{{! row['format_type'] }}" placeholder="Type" data-value="{{! row['format_type'] }}"/></td>
                    <td><gs-checkbox mini column="col_not_null" value="{{= row['col_not_null'] === "-1" }}" data-value="{{= row['col_not_null'] === "-1" }}"/></td>
                    <td><gs-text mini column="col_default" value="{{! row['col_default'] }}" placeholder="Default" data-value="{{! row['col_default'] }}"/></td>
                    <td><gs-text mini column="col_collation" value="{{! row['col_collation'] === '0' ? '' : row['col_collation'] }}" placeholder="Collation"/></td>
                */});

                // build tbody contents
                strRecords = doT.template(
                                    '{{ var row, i, len, qs = GS.qryToJSON(GS.getQueryString());\n' +
                                    '\n' +
                                    'for (i = 0, len = jo.length; i < len; i += 1) {\n' +
                                    '    row = jo[i]; }}\n' +
                                    '    <tr>' + recordHTML + '</tr>\n' +
                                    '{{ } }}')(arrRecords);
                strRecords += '<tr id="column-insert">';
                strRecords += '<th>&gt;</th>';
                strRecords += '<td></td>';
                strRecords += '<td><gs-text mini        column="attname"        placeholder="Column Name"/></td>';
                strRecords += '<td><gs-text mini        column="format_type"    placeholder="Type"/></td>';
                strRecords += '<td><gs-checkbox mini    column="col_not_null"   value="0"/></td>';
                strRecords += '<td><gs-text mini        column="col_default"    placeholder="Default"/></td>';
                strRecords += '<td><gs-text mini        column="col_collation"  placeholder="Collation"/></td>';
                strRecords += '</tr>';

                //console.log(strRecords);

                document.getElementById('div-column-list-container').innerHTML =
                    '<table>' +
                        '<thead>' +
                            '<th style="width: 3em;">#</th>' +
                            '<th style="width: 2em;"></th>' +
                            '<th>Name</th>' +
                            '<th style="width: 14em;">Type</th>' +
                            '<th style="width: 3em;">NOT NULL?</th>' +
                            '<th>Default</th>' +
                            '<th>Collation</th>' +
                        '</thead>' +
                        '<tbody>' +
                            strRecords +
                        '</tbody>' +
                    '</table>';

                document.getElementById('column-insert').addEventListener('keydown', function __________THIS_FUNCTION__________(event) {
                    if (event.keyCode.toString() === GS.keyCode('ENTER')) {
                        var element = event.target,
                            row = GS.findParentTag(element, 'tr'),
                            strColumnInsert = '';

                        element = element.tagName === 'GS-CHECKBOX' ? element : element.parentNode;
                        row.children[0].innerText = (arrRecords.length += 1);
                        row.children[1].innerHTML = '<gs-button mini icononly class="drag-handle" icon="bars"></gs-button>';

                        row.removeAttribute('id');

                        strColumnInsert += '<tr id="column-insert">';
                        strColumnInsert += '<th>&gt;</th>';
                        strColumnInsert += '<td></td>';
                        strColumnInsert += '<td><gs-text mini        column="attname"        placeholder="Column Name" /></td>';
                        strColumnInsert += '<td><gs-text mini        column="format_type"    placeholder="Type" /></td>';
                        strColumnInsert += '<td><gs-checkbox mini    column="col_not_null"   value="0" /></td>';
                        strColumnInsert += '<td><gs-text mini        column="col_default"    placeholder="Default" /></td>';
                        strColumnInsert += '<td><gs-text mini        column="col_collation"  placeholder="Collation" /></td>';
                        strColumnInsert += '</tr>';

                        var temp = document.createElement('table');
                        temp.innerHTML = strColumnInsert;
                        document.querySelector('#div-column-list-container tbody').appendChild(temp.querySelector('tr'));
                        document.querySelector('#column-insert gs-text').firstElementChild.focus();

                        this.removeEventListener('keydown', __________THIS_FUNCTION__________);
                        document.getElementById('column-insert').addEventListener('keydown', __________THIS_FUNCTION__________);

                        arrColumn.push({
                            updated: {
                                name: arrRecords[i].attname,
                                type: arrRecords[i].format_type
                            }
                        });
                    }
                });

                document.getElementById('div-column-list-container').addEventListener('change', function (event) {
                    if (event.target.tagName === 'GS-CHECKBOX' && event.target.parentNode.parentNode.hasAttribute('id')) {
                        // We are in the insert column row
                        GS.triggerEvent(event.target, 'keydown', {
                            keyCode: parseInt(GS.keyCode('ENTER'), 10)
                        });
                    } else if (event.target.hasAttribute('data-value')) {
                        var row = GS.findParentTag(event.target, 'tr'), i = 0, len = arrColumn.length, originalName = event.target.getAttribute('data-value');
                        for (; i < len; i += 1) {
                            if (arrColumn[i].original && arrColumn[i].original.name === originalName) {
                                arrColumn[i].updated.name = row.children[2].children[0].value;
                                arrColumn[i].updated.type = row.children[3].children[0].value;

                                break;
                            }
                        }
                    }
                });

                // create sort handle function
                sortColumnHandler = function (dragParent, event) {
                    var intTop = GS.mousePosition(event).top, matchedElement, bolMatchedLast, i, len,
                        offsetsCache = dragParent.offsetsCache, borderElement = dragParent.dragBorderElement,
                        ghostElement = dragParent.dragGhostElement;

                    ghostElement.style.top = (intTop - (ghostElement.offsetHeight / 2)) + 'px';

                    if (offsetsCache[0].top > intTop) {
                        matchedElement = offsetsCache[0].element;
                        bolMatchedLast = false;

                    } else {
                        bolMatchedLast = false;
                        for (i = 0, len = offsetsCache.length; i < len; i += 1) {
                            if (offsetsCache[i + 1]) {
                                if (offsetsCache[i].top <= intTop &&
                                    offsetsCache[i].top + ((offsetsCache[i + 1].top - offsetsCache[i].top) / 2) > intTop) {

                                    matchedElement = offsetsCache[i].element;
                                    break;

                                } else if (offsetsCache[i].top <= intTop &&
                                            offsetsCache[i].top + ((offsetsCache[i + 1].top - offsetsCache[i].top) / 2) <= intTop &&
                                            offsetsCache[i + 1].top > intTop) {
                                    matchedElement = offsetsCache[i + 1].element;
                                    break;
                                }
                            } else {
                                if (offsetsCache[i].top + (offsetsCache[i].height / 2) >= intTop) {
                                    matchedElement = offsetsCache[i].element;
                                    break;

                                } else if (offsetsCache[i].top + (offsetsCache[i].height / 2) <= intTop) {
                                    matchedElement = offsetsCache[i].element;
                                    bolMatchedLast = true;
                                    break;
                                }
                            }
                        }
                    }

                    //console.log(bolMatchedLast); //matchedElement,

                    if (matchedElement !== dragParent.matchedElement || bolMatchedLast !== dragParent.bolMatchedLast) {
                        if (bolMatchedLast === true) {
                            dragParent.insertBefore(borderElement, dragParent.querySelector('#column-insert'));

                        } else {
                            dragParent.insertBefore(borderElement, matchedElement);
                        }

                        dragParent.matchedElement = matchedElement;
                        dragParent.bolMatchedLast = bolMatchedLast;
                    }

                    //console.log('sort', intTop);//, event, ghostElement);
                };

                // bind sort handles
                document.getElementById('div-column-list-container').addEventListener(evt.mousedown, function (event) {
                    var dragParent = event.target.parentNode.parentNode.parentNode, dragLine, mousemoveHandler, mouseupHandler, arrElements, i, len;

                    if (event.target.classList.contains('drag-handle')) {
                        // save drag line
                        dragLine = event.target.parentNode.parentNode;

                        // save a cache of line offsets
                        arrElements = xtag.toArray(dragParent.children);
                        dragParent.offsetsCache = [];
                        // the - 1 is so that the insert record is ignored
                        for (i = 0, len = arrElements.length - 1; i < len; i += 1) {
                            dragParent.offsetsCache.push({
                                'element': arrElements[i],
                                'top': GS.getElementOffset(arrElements[i]).top,
                                'height': arrElements[i].offsetHeight
                            });
                        }
                        //console.log(dragParent.offsetsCache);

                        // create and save ghost
                        dragParent.dragGhostElement = document.createElement('table');
                        dragParent.dragGhostElement.appendChild(dragLine.cloneNode(true));
                        dragParent.dragGhostElement.setAttribute('style', 'position: absolute;' +
                                                                          'left: 0; top: 0;' +
                                                                          'padding: 2px; opacity: 0.6;' +
                                                                          'background-color: #F0F0F0;' +
                                                                          'border: 1px solid #000000;' +
                                                                          'width: ' + dragLine.clientWidth + 'px;');

                        dragParent.appendChild(dragParent.dragGhostElement);

                        // create and save border element
                        dragParent.dragBorderElement = document.createElement('div');
                        dragParent.dragBorderElement.setAttribute('style', 'position:relative;');
                        dragParent.dragBorderElement.innerHTML = '<div style="position: absolute;' +
                                                                              'top: -2px; left: -2px;' +
                                                                              'width: ' + dragLine.clientWidth + 'px; padding: 2px;' +
                                                                              'background-color: #00CC00;"></div>';

                        dragParent.appendChild(dragParent.dragBorderElement);

                        // call sort handler
                        sortColumnHandler(dragParent, event);

                        // bind mousemove and mouseup
                        mousemoveHandler = function (event) {
                            if (event.which === 0 && !evt.touchDevice) {
                                mouseupHandler(event);

                            } else {
                                sortColumnHandler(dragParent, event);
                                event.preventDefault();
                            }
                        };

                        mouseupHandler = function (event) {
                            var arrRowNumber;

                            if (dragParent.bolMatchedLast) {
                                dragParent.insertBefore(dragLine, dragParent.querySelector('#column-insert'));
                            } else {
                                dragParent.insertBefore(dragLine, dragParent.matchedElement);
                            }

                            document.body.removeEventListener(evt.mousemove, mousemoveHandler);
                            document.body.removeEventListener(evt.mouseup, mouseupHandler);
                            dragParent.removeChild(dragParent.dragGhostElement);
                            dragParent.removeChild(dragParent.dragBorderElement);

                            // I am using xtag.query so that I already have an array
                            arrRowNumber = xtag.query(dragParent, 'tbody tr:not(#column-insert) th:first-child');
                            arrRowNumber.forEach(function (curElement, i) {
                                curElement.innerText = (i + 1).toString();
                            });
                        };

                        document.body.addEventListener(evt.mousemove, mousemoveHandler);
                        document.body.addEventListener(evt.mouseup, mouseupHandler);
                    }
                });
            }

            function refreshEditor(strOID) {
                var strTableColumns = '', i = 0;
                strConstraints = '';
                strTableName = '';

                GS.requestRawFromSocket(GS.envSocket, listQuery.tableData.replace(/\{\{INTOID\}\}/g, strOID), function (data) {
                    //console.log('1', i, data);

                    if (data.intQueryNumber <= 1) {
                        if (data.strMessage !== '\\.') {
                            if (data.intQueryNumber === 0) {
                                strConstraints += data.strMessage;
                            } else {
                                strGrantsEtc = data.strMessage;
                            }

                        } else if (data.strMessage === '\\.' && data.intQueryNumber === 1) {
                            var arrConstraints = strConstraints.split('\n'), len = arrConstraints.length;
                            //console.log(strConstraints);
                            strConstraints = '';
                            arrConstraints.forEach(function (curCon, i) {
                                strConstraints += '\t';
                                strConstraints += GS.decodeFromTabDelimited(curCon);
                                strConstraints += (i + 1) < len ? ',\n' : '\n';
                            });
                            var arrTriggersEtc = strGrantsEtc.split('\n'), len = arrTriggersEtc.length;
                            strGrantsEtc = '';
                            arrTriggersEtc.forEach(function (cur, i) {
                                strGrantsEtc += '\t';
                                strGrantsEtc += GS.decodeFromTabDelimited(cur);
                                strGrantsEtc += (i + 1) < len ? ',\n' : '\n';
                            });

                            GS.requestRawFromSocket(GS.envSocket, ml(function () {/*
                                     SELECT pg_namespace.nspname, relname, relhasoids, array_to_string(reloptions, E',\n\t') AS reloptions
                                       FROM pg_class
                                  LEFT JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
                                      WHERE pg_class.oid = {{INTOID}};
                                */}).replace(/\{\{INTOID\}\}/g, strOID), function (data) {

                                //console.log('2', data);

                                if (data.strMessage !== '\\.' && data.intQueryNumber === 0) {
                                    strTableName += data.strMessage;
                                } else if (data.strMessage === '\\.' && data.intQueryNumber === 0) {
                                    strSchemaName = GS.decodeFromTabDelimited(strTableName.substring(0, strTableName.indexOf('\t')));
                                    strTableName = strTableName.substring(strTableName.indexOf('\t') + 1);

                                    strHasOids = GS.decodeFromTabDelimited(strTableName.substring(strTableName.indexOf('\t')))[0] === 't' ? 'TRUE' : 'FALSE';
                                    strRelOptions = strTableName.substring(strTableName.indexOf('\t') + 1);
                                    strRelOptions = strRelOptions.substring(strRelOptions.indexOf('\t') + 1);
                                    strRelOptions = GS.decodeFromTabDelimited(strRelOptions.substring(strRelOptions.indexOf('\t')));

                                    strTableName = GS.decodeFromTabDelimited(strTableName.substring(0, strTableName.indexOf('\t')));

                                    //console.log(strSchemaName, strTableName, strHasOids, strRelOptions);
                                    var strColumns = '';
                                    GS.requestRawFromSocket(GS.envSocket, ml(function () {/*
                                         SELECT attname, format_type(atttypid, atttypmod),
                                                (CASE WHEN attnotnull THEN '-1' ELSE '0' END) AS col_not_null,
                                                (CASE WHEN atthasdef THEN pg_catalog.pg_get_expr(adbin, adrelid) ELSE '' END) AS col_default,
                                                (CASE WHEN attcollation <> 0 THEN pg_collation.collname ELSE '0' END) AS col_collation
                                           FROM pg_attribute
                                      LEFT JOIN pg_attrdef ON pg_attrdef.adrelid = pg_attribute.attrelid AND pg_attrdef.adnum = pg_attribute.attnum
                                      LEFT JOIN pg_collation ON pg_collation.oid = pg_attribute.attcollation
                                          WHERE pg_attribute.attisdropped IS FALSE AND pg_attribute.attnum > 0 AND attrelid = {{INTOID}}
                                       ORDER BY attnum ASC*/}).replace(/\{\{INTOID\}\}/g, strOID), function (data) {

                                        //console.log(data);

                                        if (data.intQueryNumber === 0 && data.strMessage !== '\\.') {
                                            //console.log(data);
                                            strColumns += (strColumns ? '\n' : '') + data.strMessage;

                                        } else if (data.intQueryNumber === 0 && data.strMessage === '\\.') {
                                            getSingleCellData(ml(function () {/*
                                                SELECT quote_ident(rolname)
                                                    FROM pg_roles
                                                    INNER JOIN pg_class ON relowner = pg_roles.oid
                                                    WHERE pg_class.oid = {{INTOID}}
                                            */}).replace(/\{\{INTOID\}\}/g, strOID), function (owner) {
                                                strOwner = owner;
                                                initTableDesign(data.arrColumnNames, strColumns);
                                            });
                                        }
                                    });
                                }
                            });
                        }
                    }
                });
            }

            document.addEventListener('DOMContentLoaded', function () {
                var strQueryString = GS.getQueryString(),
                    strOID = GS.qryGetVal(strQueryString, 'oid'),
                    templateElement;

                //console.log('1***', strOID);

                // if there is no oid: ask for one
                if (!strOID) {
                    templateElement = document.createElement('template');
                    templateElement.setAttribute('data-theme', 'error');

                    templateElement.innerHTML = ml(function () {/*
                        <gs-page>
                            <gs-header><center><h3>Missing Parameter</h3></center></gs-header>
                            <gs-body padded>
                                This page needs an object ID to edit. You can manually set one by typing one in and clicking "Go".
                                <br />
                                <label><b>Manual OID:</b></label>
                                <gs-text id="text-page-load-oid"></gs-text>
                            </gs-body>
                            <gs-footer>
                                <gs-button dialogclose listen-for-return>Go</gs-button>
                            </gs-footer>
                        </gs-page>
                    */});

                    GS.openDialog(templateElement, '', function () {
                        window.location.search = '?oid=' + encodeURIComponent(document.getElementById('text-page-load-oid').value);
                    });

                // if there is an oid
                } else {
                    //console.log('2***', strOID);
                    refreshEditor(strOID);
                }

                document.getElementById('button-generate-script').addEventListener('click', function (event) {
                    var strSchemaOID = '';
                    GS.addLoader('generate-script', 'Loading...');
                    GS.requestRawFromSocket(GS.envSocket,
                                            'SELECT pg_class.relnamespace FROM pg_class WHERE pg_class.oid = ' + strOID,
                                            function (data, error) {
                        if (!error) {
                            if (data.strMessage !== '\\.' && data.intCallbackNumber === 0) {
                                getDump(data.strMessage);
                            }
                        } else {
                            GS.webSocketErrorDialog(data);
                            GS.removeLoader('generate-script');
                        }
                    });
                });
            });

            window.addEventListener('load', function () {
                "use strict";
                zoomStart();
            });
        </script>
        
        <style>
            #div-column-list-container {
                display: block;
                position: relative;
                height: 100%;
                overflow: auto;
            }
            #div-column-list-container table {
                border-left: 1px solid #ddd;
            }
            
            #div-column-list-container table input {
                display: block;
                resize: none;
                width: 100%;
                border: 0 none;
                cursor: text;
                padding: 0 0.1em;
                
                -webkit-box-sizing: border-box;
                -moz-box-sizing: border-box;
                -ms-box-sizing: border-box;
                -o-box-sizing: border-box;
                box-sizing: border-box;
            }
            
            #div-column-list-container th, #div-column-list-container td {
                padding: 0.1em;
                cursor: pointer;
                
                -webkit-touch-callout: none;
                -webkit-user-select: none;
                -khtml-user-select: none;
                -moz-user-select: none;
                -ms-user-select: none;
                -o-user-select: none;
                user-select: none;
            }
            
            #div-column-list-container td gs-checkbox {
                padding-top: 0.5em;
            }
            
            #div-column-list-container thead th {
                cursor: s-resize;
                overflow: hidden;
            }
        </style>
        <script src="../../js/settings.js" type="text/javascript"></script>
        <script>
            if (window.parent) {
                window.parent.addEventListener('resize', function () {
                    if (localStorage && localStorage.customCSS) {
                        refreshCustomCSS(localStorage.customCSS);
                    }
                    /*
                    if (localStorage && localStorage.customCSS && document.getElementById('customCss')) {
                        document.getElementById('customCss').innerHTML = localStorage.customCSS;
                    }
                    */
                });
            }
        </script>
        <style id="customCss"></style>
    </head>
    <body>
        <gs-page>
            <gs-body padded>
                <gs-button id="button-generate-script">Generate Script</gs-button><br />
                <div id="div-column-list-container"></div>
            </gs-body>
        </gs-page>
    </body>
</html>